package com.uiotsoft.small.sampler;

import cn.hutool.json.JSONUtil;
import com.uiotsoft.small.app.sampler.simple.AppBusinessSampler;
import com.uiotsoft.small.mqtt.MqttClientOld;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ComBusinessSampler extends AbstractJavaSamplerClient {
    private String method;
    private String token;
    private String data;
    private String pubTopic;
    private String sendMsg;
    private String subTopic;
    private int receiveType;
    private String msgId;
    private ComHttpClient httpClient;
    private volatile MqttClientOld clientOld;
    private static final Logger log = LoggerFactory.getLogger(AppBusinessSampler.class);

    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("protocol", "http.post/mqtt");
        params.addArgument("type", "app.local/host");
        params.addArgument("time", "${__time(,)}");
        params.addArgument("method", "");
        params.addArgument("token", "");
        params.addArgument("data", "");
        params.addArgument("pubTopic", "");
        params.addArgument("sendMsg", "");
        params.addArgument("subTopic", "");
        params.addArgument("receiveType", "1");
        return params;
    }

    @Override
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        JMeterVariables vars = JMeterContextService.getContext().getVariables();
        SampleResult results = new SampleResult();
        results.setDataEncoding("UTF-8");
        results.sampleStart();
        String protocol = javaSamplerContext.getParameter("protocol");
        String type = javaSamplerContext.getParameter("type");
        if (protocol.toLowerCase().startsWith("http")){
            String time = javaSamplerContext.getParameter("time");
            method = javaSamplerContext.getParameter("method");
            token = javaSamplerContext.getParameter("token");
            data = javaSamplerContext.getParameter("data");
            String httpResult = null;
            if (type.toLowerCase().startsWith("app")){
                httpClient = (ComHttpClient) vars.getObject("appHttpClient");
            }else if (type.toLowerCase().startsWith("host")){
                httpClient = (ComHttpClient) vars.getObject("hostHttpClient");
            }
            httpClient.setMethod(method);
            httpClient.setToken(token);
            if (protocol.toLowerCase().contains("post")){
                httpResult = httpClient.requestPost(data,time);
            }else if (protocol.toLowerCase().contains("get")){
                httpResult = httpClient.requestGet(data);
            }
            results.setSuccessful(true);
            results.setRequestHeaders(httpClient.getHeaders(data,time));
            results.setSamplerData(data);
            results.setResponseData(httpResult, "UTF-8");
        }else if (protocol.toLowerCase().startsWith("mqtt")){
            pubTopic = javaSamplerContext.getParameter("pubTopic");
            sendMsg = javaSamplerContext.getParameter("sendMsg");
            subTopic = javaSamplerContext.getParameter("subTopic");
            receiveType = Integer.parseInt(javaSamplerContext.getParameter("receiveType"));
            msgId = JSONUtil.parseObj(sendMsg).getJSONObject("header").getStr("msgId");
            if (type.toLowerCase().startsWith("app")){
                if (type.toLowerCase().contains("local")){
                    clientOld = (MqttClientOld) vars.getObject("appLocalMqttClient");
                }else {
                    clientOld = (MqttClientOld) vars.getObject("appMqttClient");
                }
            }else if (type.toLowerCase().startsWith("host")){
                clientOld = (MqttClientOld) vars.getObject("hostMqttClient");
            }
            if (clientOld != null){
                if(pubTopic != null && !pubTopic.equals("")){
                    boolean publish = clientOld.publish(pubTopic, sendMsg);
                    if (publish){
                        results.setSamplerData(sendMsg);
                        if (!subTopic.equals("") && subTopic != null){
                            boolean flag = false;
                            int num = 0;
                            if (receiveType>100){
                                flag = true;
                            }
                            long start = System.currentTimeMillis();
                            while (true){
                                String topic = clientOld.getTopic();
                                String mqttResult = clientOld.getResult();
                                if (mqttResult != null && topic != null){
                                    String msgIdReceive = JSONUtil.parseObj(mqttResult).getJSONObject("header").getStr("msgId");
                                    if (topic.equals(subTopic) && msgIdReceive.equals(msgId)){
                                        num ++;
                                        if (num == receiveType){
                                            log.info("\n******客户端接收消息成功……\n******msgId：{}\n******clientId：{}\n******topic：{}:\n******content{}",msgId,clientOld.getClientId(),topic,mqttResult);
                                            results.setSuccessful(true);
                                            results.setResponseData(mqttResult, "UTF-8");
                                            results.setResponseCodeOK();
                                            break;
                                        }
                                    }
                                }
                                if (flag){
                                    long end = System.currentTimeMillis();
                                    if (end-start > receiveType){
                                        log.info("\n******客户端{}接收消息超时……",clientOld.getClientId());
                                        results.setSuccessful(false);
                                        results.setResponseData("receive timeout", "UTF-8");
                                        results.setResponseCode("500");
                                        break;
                                    }
                                }

                            }
                        }else {
                            results.setSuccessful(true);
                            results.setResponseData("publish success", "UTF-8");
                            results.setResponseCodeOK();
                        }
                    }else {
                        results.setSuccessful(false);
                        results.setResponseData("publish fail", "UTF-8");
                        results.setResponseCode("400");
                    }
                }

            }else {
                results.setSuccessful(false);
                results.setResponseData("connect null", "UTF-8");
                results.setResponseCode("500");
            }
        }
        results.sampleEnd();
        return results;
    }
}
